package com.lemt.index.filter;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lemt.common.utils.JwtUtil;
import com.lemt.user.entity.*;
import com.lemt.user.mapper.*;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
@Order(value = 1)
public class AuthFilter extends OncePerRequestFilter {

    @Resource
    private UserMapper userMapper;
    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RoleMeauMapper roleMeauMapper;

    @Resource
    private MeauMapper meauMapper;
    @Resource
    private RoleMapper roleMapper;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//
//        String requestURI = request.getRequestURI();
//        log.info("拦截请求+{}",requestURI);
//        List<String> strings = new ArrayList<>();
//        strings.add("/user/login");
//        strings.add("/user/register");
//
//        strings.forEach(item -> {
//            if (requestURI.equals(item)){
//                try {
//                    filterChain.doFilter(request,response);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                } catch (ServletException e) {
//                    e.printStackTrace();
//                }
//            }
//        });
        // 获取请求头的Authorization的信息
        String token = request.getHeader("Authorization");
        log.info("从请求头获取数据 Authorization ==》{}",token);
        if (StringUtils.isBlank(token)) {
            token = request.getParameter("token");
            log.info("从请求参数中获取token ==》 {}",token);
        }
        // 没有token
        if (StringUtils.isBlank(token)) {
            //放行,因为后面的会抛出相应的异常
            log.info("没有查询到相应的token ==》 直接放行");
            filterChain.doFilter(request, response);
            return;
        }
        // 非法token
        String account = null;
        try {
            // 这里解析jwt
            log.info("进入jwt解析");
            Claims parse = JwtUtil.parse(token);
            account = (String) parse.get("phone");

        } catch (Exception e) {
            throw new RuntimeException("非法token!");
        }
        log.info("进入数据库查询（user）");
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        // 如果account有长度的话就进入查询
        queryWrapper.eq(org.springframework.util.StringUtils.hasLength(account),User::getPhone,account);
        User user = userMapper.selectOne(queryWrapper);
        if (Objects.isNull(user)) {
            throw new RuntimeException("非法token!");
        }

        // 获取权限
        Authentication authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), grantedAuthorities(user.getId()));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request,response);

    }

    /**
     * 获取权限列表
     * @param userId
     * @return
     */
    private List<GrantedAuthority> grantedAuthorities(Integer userId){
        log.info("进入获取用户权限的方法==》 grantedAuthorities");

        List<GrantedAuthority> roles = new ArrayList<>();

        List<UserRole> userRoles = userRoleMapper.selectList(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId));
        log.info("获取到user_role中的信息");
        Set<Integer> set = userRoles.stream().map(i -> i.getRoleId()).collect(Collectors.toSet());
        if (set.isEmpty()){
            log.info("set集合role为空》{}",set);
            return roles;
        }
        log.info("获取role中的信息");
        List<Role> roleList = roleMapper.selectBatchIds(set);
        Set<Integer> setMeau = new HashSet<>();
        for (Role role : roleList) {
            log.info("role不为空》{}",role);
            List<RoleMeau> roleMeaus = roleMeauMapper.selectList(new LambdaQueryWrapper<RoleMeau>().eq(RoleMeau::getRoleId, role.getId()));
            log.info("{}",roleMeaus);
            for (RoleMeau roleMeau:roleMeaus){
                log.info("{}",roleMeau);
                setMeau.add(roleMeau.getMeauId());
            }
        }
        if (setMeau.isEmpty()){
            return roles;
        }
        List<Meau> meaus = meauMapper.selectBatchIds(setMeau);
        for (Meau meau : meaus){
            log.info("",meau);
            roles.add(new SimpleGrantedAuthority(meau.getMeauName()));
        }
        log.info("{}",roles);
        return roles;
    }


}
